#ifndef HOUGHSPACE_H
#define HOUGHSPACE_H

/**
 * \file HoughSpace.h
 * \brief Fichier contenant la déclaration de la classe HoughSpace.
 */

#include <vector>
#include "Circle.h"
#include "HoughFrame.h"

#define RESOLUTION 0
#define SIZE 1

using namespace std;

class HoughSpace
{
	/* \class HoughSpace
	 * \brief Cette classe représente un espace de hough pour les cercles sous la forme d'un tableau à trois dimensions (a,b,r).
	 */
	private :
	
	Point bot;							/*!<Point de coordonnées a, b et r minimum.*/
	Point top;							/*!<Point de coordonnées a, b et r maximum.*/
			
	int nbFrameA;						/*!<Nombre de cases selon a de la grille.*/
	int nbFrameB;						/*!<Nombre de cases selon b de la grille.*/
	int nbFrameR;						/*!<Nombre de cases selon r de la grille.*/
	
	float frameSizeA;					/*!<Taille d'une case de l'espace selon l'axe a.*/
	float frameSizeB;					/*!<Taille d'une case de l'espace selon l'axe b.*/
	float frameSizeR;					/*!<Taille d'une case de l'espace selon l'axe r.*/
	
	float aFrameMax;					/*!<a de la case de plus haut score de l'espace.*/
	float bFrameMax;					/*!<b de la case de plus haut score de l'espace.*/
	float rFrameMax;					/*!<r de la case de plus haut score de l'espace.*/
	
	int scoreMax;						/*!<score de la case de plus haut score de l'espace.*/
	int scoreTotal;						/*!<score total de l'espace.*/
	
	HoughFrame*** frames;				/*!<Tableau trois dimensions de cases de Hough.*/
	
	public :
	
	/*!
	 *  \brief Constructeur de la classe HoughSpace
	 *
	 *  Constructeur de la classe HoughSpace, tous les attributs sont initialisés à 0 et à NULL.
	 *
	 */
	HoughSpace();
			
	/*!
	 *  \brief Constructeur de la classe HoughSpace
	 *
	 *  Constructeur de la classe HoughSpace
	 *
	 *  \param _mode : mode de création de l'espace : si _mode vaut RESOLUTION, _a _b et _r représenteront le nombre de cases de l'espace dans ces axes. S'il vaut SIZE alors ils définissent la taille des cases selon chaque axe.
	 *  \param _bot : Coin inferieur gauche de l'espace.
	 *  \param _top : Coin superieur droit de l'espace.
	 *  \param _a : définit, selon le mode, la taille d'une case de l'espace selon l'axe a, ou le nombre de case sur cet axe.
	 *  \param _b : définit, selon le mode, la taille d'une case de l'espace selon l'axe b, ou le nombre de case sur cet axe.
	 *  \param _r : définit, selon le mode, la taille d'une case de l'espace selon l'axe r, ou le nombre de case sur cet axe.
	 */
	HoughSpace(int _mode, Point _bot, Point _top, float _a, float _b, float _r);
	
	/*!
	 *  \brief Destructeur de HoughSpace.
	 *
	 *  Destructeur de HoughSpace.
	 *
	 */
	~HoughSpace();
	
	/*!
	 *  \brief Initialise un espace de Hough non encore initialisé (son attribut frames est encore NULL).
	 *
	 *  Agit de la même manière que le constructeur de la classe HoughSpace
	 *
	 *  \param _mode : mode de création de l'espace : si _mode vaut RESOLUTION, _a _b et _r représenteront le nombre de cases de l'espace dans ces axes. S'il vaut SIZE alors ils définissent la taille des cases selon chaque axe.
	 *  \param _bot : Coin inferieur gauche de l'espace.
	 *  \param _top : Coin superieur droit de l'espace.
	 *  \param _a : définit, selon le mode, la taille d'une case de l'espace selon l'axe a, ou le nombre de case sur cet axe.
	 *  \param _b : définit, selon le mode, la taille d'une case de l'espace selon l'axe b, ou le nombre de case sur cet axe.
	 *  \param _r : définit, selon le mode, la taille d'une case de l'espace selon l'axe r, ou le nombre de case sur cet axe.
	 *
	 *  \retun : void
	 */
	void init(int _mode, Point _bot, Point _top, float _a, float _b, float _r);

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à nbFrameA
	 *
	 * \return : Renvoie le nombre de cases selon A.
	 */
	int getNbFrameA();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à nbFrameB
	 *
	 * \return : Renvoie le nombre de cases selon B.
	 */
	int getNbFrameB();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à nbFrameR
	 *
	 * \return : Renvoie le nombre de cases selon R.
	 */
	int getNbFrameR();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à frameSizeA
	 *
	 * \return : Renvoie la taille des cases de l'espace de Hough selon A.
	 */
	float getFrameSizeA();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à frameSizeB
	 *
	 * \return : Renvoie la taille des cases de l'espace de Hough selon B.
	 */
	float getFrameSizeB();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à frameSizeR
	 *
	 * \return : Renvoie la taille des cases de l'espace de Hough selon R.
	 */
	float getFrameSizeR();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à aFrameMax
	 *
	 * \return : Renvoie la valeur de a pour la case de score maximum.
	 */
	float getAFrameMax();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à bFrameMax
	 *
	 * \return : Renvoie la valeur de b pour la case de score maximum.
	 */
	float getBFrameMax();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à rFrameMax
	 *
	 * \return : Renvoie la valeur de r pour la case de score maximum.
	 */
	float getRFrameMax();	

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à bot
	 *
	 * \return : Renvoie le point bot.
	 */
	Point getBot();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à top
	 *
	 * \return : Renvoie le point top.
	 */
	Point getTop();

	/*!
	 *  \brief Accesseur de la classe Hough
	 *
	 *  Accède à scoreMax
	 *
	 * \return : Renvoie le score de la case de score maximum.
	 */
	int getScoreMax();	

	/*!
	 *  \brief Renvoie la valeur de la case de coorconnées (a,b,r)
	 *
	 *  Renvoie la valeur de la case de coorconnées (a,b,r)
	 *
	 * \param _a : Coordonnée a.
	 * \param _b : Coordonnée b.
	 * \param _r : Coordonnée r.
	 *
	 * \return : Valeur de la case.
	 */
	int getScore(int _a, int _b, int _r);

	/*!
	 *  \brief Renvoie la valeur de scoreTotal
	 *
	 *  Renvoie la valeur du nombre total de points de l'espace de Hough
	 *
	 * \return : Valeur de scoreTotal.
	 */
	int getScoreTotal();

	/*!
	 *  \brief Renvoie une copie de la case de coorconnées (a,b,r)
	 *
	 *  Renvoie une copie de la case de coorconnées (a,b,r)
	 *
	 * \param _a : Coordonnée _a.
	 * \param _b : Coordonnée _b.
	 * \param _r : Coordonnée _r.
	 *
	 * \return : Copie de la case.
	 */
	HoughFrame getHoughFrame(int _a, int _b, int _r);

	/*!
	 *  \brief Modificateur de la classe HoughSpace
	 *
	 *  Modifie la valeur de aFrameMax.
	 *
	 * \param _aFrameMax : Nouvelle valeur de aFrameMax.
	 *
	 * \return : vod
	 */
	void setAFrameMax(float _aFrameMax);

	/*!
	 *  \brief Modificateur de la classe HoughSpace
	 *
	 *  Modifie la valeur de bFrameMax.
	 *
	 * \param _bFrameMax : Nouvelle valeur de bFrameMax.
	 *
	 * \return : void
	 */
	void setBFrameMax(float _bFrameMax);

	/*!
	 *  \brief Modificateur de la classe HoughSpace
	 *
	 *  Modifie la valeur de rFrameMax.
	 *
	 * \param _rFrameMax : Nouvelle valeur de rFrameMax.
	 *
	 * \return : void
	 */
	void setRFrameMax(float _rFrameMax);
	
	/*!
	 *  \brief Modificateur de la classe HoughSpace
	 *
	 *  Modifie le score de scoreMax.
	 *
	 * \param _scoreMax : Nouvelle valeur de scoreMax.
	 *
	 * \return : void
	 */
	void setScoreMax(int _scoreMax);
	
	/*!
	 *  \brief Remplit l'espace de Hough
	 *
	 *  Remplit l'espace de Hough à partir d'un ensemble de cercles.
	 *
	 * \param _tabCircles : vector de cercles.
	 *
	 * \return : void
	 */
	void fill(vector <Circle> _tabCircles);
	
	/*!
	 *  \brief Méthode permettant d'ajouter à un tableau les cercles significatifs dans un espace de Hough.
	 *
	 *  Méthode qui ajoute à un tableau les cercles significatifs d'un espace de Hough - i.e. les cercles représentés par des cases de score supérieur à un sueil.
	 *
	 *  \param _rslt : Tableau de cercle auquel on ajoute les cercles significatifs trouvés.
	 *  \param _thresh : seuil au delà duquel le score d'une case de l'espace devient représentatif.
	 *
	 *  \return : void
	 */
	void threshold(vector <Circle> &_rslt, int _thresh);

	/*!
	 *  \brief Méthode permettant de récupérer les cercles significatifs dans l'espace de Hough.
	 *
	 *  Méthode qui récupère les cercles significatifs de l'espace de Hough - i.e. les cercles représentés par des cases de score supérieur à un sueil.
	 *
	 *  \param _thresh : seuil au delà duquel le score d'une case de l'espace devient représentatif.
	 *
	 *  \return : Renvoie un vecteur de cercle contenant tous les cercles représentatifs situés dans cet espace.
	 */
	vector<Circle> threshold ( int _thresh );

	/*!
	 *  \brief Méthode permettant de récupérer les cercles significatifs dans l'espace de Hough.
	 *
	 *  Méthode qui récupère les cercles significatifs de l'espace de Hough - i.e. les cercles représentés par des cases de score supérieur à un sueil.
	 *	Cette méthode utilise un seuil variable, en fonction du nombre de points dans l'esapce de Hough.
	 *	Plus le nombre de points est important, plus le seuil sera haut, et inversement. 
	 *
	 *  \param _thresh1 : seuil minimum au delà duquel le score d'une case de l'espace devient représentatif.
	 *  \param _thresh2 : seuil maximum au delà duquel le score d'une case de l'espace devient représentatif.
	 *
	 *  \return : Renvoie un vecteur de cercle contenant tous les cercles représentatifs situés dans cet espace.
	 */
	vector<Circle> threshold(float _thresh1, float _thresh2);
	
	/*!
	 *  \brief Méthode permettant d'incrémenter la valeur d'une case de l'espace de Hough.
	 *
	 *  Méthode permettant d'incrémenter la valeur de la case de l'espace de Hough de coordonnées (a,b,r).
	 *
	 *  \param _a : coordonnée a de la case à incrémenter.
	 *  \param _b : coordonnée b de la case à incrémenter.
	 *  \param _r : coordonnée r de la case à incrémenter.
	 *
	 *  \return : void
	 */
	void increment ( int _a, int _b, int _r );

	/*!
	 *  \brief Méthode permettant d'incrémenter la valeur d'une case de l'espace de Hough.
	 *
	 *  Méthode permettant d'incrémenter plusieurs fois la valeur de la case de l'espace de Hough de coordonnées (a,b,r).
	 *
	 *  \param _a : coordonnée a de la case à incrémenter.
	 *  \param _b : coordonnée b de la case à incrémenter.
	 *  \param _r : coordonnée r de la case à incrémenter.
	 *  \param _val : nombre d'incrémentations.
	 *
	 *  \return : void
	 */
	void increment ( int _a, int _b, int _r , int _val);
	
};



#endif
